-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Make zod types strip (default) instead of passthrough #792
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Amazing change! |
src/strictTypes.ts
Outdated
.object({ | ||
_meta: z.optional(RequestMetaSchema), | ||
}) | ||
.strip(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and a few others can't be strip
because otherwise while validating a JSONRpcRequest
it will remove all params that need to be passthrough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@paoloricciuti thank you!!
updated BaseRequestParamsSchema
, BaseNotificationParamsSchema
, RequestMetaSchema
, structuredContent
and metadata to have passthrough, anything else missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think no
…ema, structuredContent and metadata to have passthrough
Context
This addresses issues raised in:
.strict()
The Problem
MCP is an extensible protocol. Servers can add custom fields. But our Zod schemas using
.passthrough()
were too loose - TypeScript couldn't catch typos or provide good autocomplete.There solutions with
.strict()
schemas (see mcp-types), but that breaks when talking to servers with extensions - you get runtime errors for any unknown field.This PR approach
We now generate a
strictTypes.ts
file that uses Zod's.strip()
method instead of.passthrough()
or.strict()
:Benefits
.strict()
, this approach doesn't throw errors for unknown fieldsExample
We can't just change it now, we need to wait for the major release v2. But we still can deprecate the types and start using typesafe eversion.
Migration Guide
Example for new projects
Use
strictTypes.js
by default:For Existing Projects
types.js
tostrictTypes.js
If You Need Extensibility
If you need to preserve additional fields, you have options:
types.js
(deprecated but still available)Implementation Details
The
strictTypes.ts
file is auto-generated fromtypes.ts
by:.passthrough()
with.strip()
.passthrough()
Until the v2 version, we need to make sure we have backwards compatibility so the generation script runs automatically during the build process to ensure both files stay in sync.
V2 version of the SDK:
types.js
file is deprecated and will be removed in a future major versionstrictTypes.js